package com.come4loves.core.dbcenter.dao;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.come4loves.core.cache.DataCache;
import com.come4loves.core.dbcenter.BaseJdbcTemplate;
import com.come4loves.core.dbcenter.DBQueue;
import com.come4loves.core.dbcenter.Entity;
/**
 * dao基类
 * @author jerry
 *
 */
public abstract class BaseDaoImpl implements BaseDao {
	protected  Logger LOGGER = LoggerFactory.getLogger(getClass());
	@Autowired
	protected BaseJdbcTemplate jdbc;
	@Autowired
	protected DBQueue dbQueue;
	@Autowired
	protected DataCache dataCache;

	/**
	 * 从缓存获取实体
	 * @param actorId
	 * @param clz
	 * @return
	 */
	@SuppressWarnings("unchecked")
	protected <T extends Entity<?>> T getFromCache(final Object actorId, final Class<T> clz) {
		Object keyStr = dataCache.getKey(actorId, clz);
		return (T) dataCache.getFromCache(keyStr, clz);
	}
	/**
	 * 设置实体到缓存
	 * @param entity
	 */
	protected <T extends Entity<?>> void set2Cache(final T entity) {
		Object key = dataCache.getKey(entity.getPkId(), entity.getClass());
		dataCache.setToCache(key , entity);
	}
	/**
	 * 获取实体
	 * @param actorId
	 * @param clz
	 * @return
	 */
	protected <K, T extends Entity<K>> T get(K actorId, Class<T> clz) {
		T entity = getExsit(actorId, clz);
		if (entity != null) {
			return entity;
		}
	
		try {
			entity = clz.newInstance();
			LOGGER.debug(String.format("entity create new,class:[%s]",clz.getName()));
		} catch (Exception e) {
			LOGGER.error("{}", e);
		} 
		entity.setPkId(actorId);
		set2Cache(entity);
		return entity;
	}
	/**
	 * 获取一个已存在的实体
	 * @param actorId
	 * @param clz
	 * @return
	 */
	protected <K, T extends Entity<K>> T getExsit(K actorId, Class<T> clz) {
		T entity = getFromCache(actorId, clz);
		if (entity != null) {
			LOGGER.debug(String.format("entity from cache.class:[%s]",clz.getName()));
			return entity;
		}
		entity = jdbc.get(clz, actorId);
		if (entity != null){
			LOGGER.debug(String.format("entity from db.class:[%s]",clz.getName()));
			entity.setNewEntity(false);
			set2Cache(entity);
			return entity;
		}
		
		return null;
	}
	
	@Override
	public void updateQueue(Entity<?> entity) {
		set2Cache(entity);
		dbQueue.updateQueue(entity);
	}
	
	@Override
	public DataCache getDataCache() {
		return dataCache;
	}
	
	
}
